package com.tong.lettuce.lock.configure;

import com.tong.lettuce.lock.annotation.RedisLock;
import com.tong.lettuce.lock.core.LettuceLock;
import com.tong.lettuce.lock.core.RedisLockable;
import com.tong.lettuce.lock.interceptor.RedisLockMethodInterceptor;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

@Slf4j
@Configuration(proxyBeanMethods = false)
public class LettuceLockConfiguration {

    @Bean
    public RedisLockable redisLockable(RedisLockProperties redisProperties) {
        log.info("redis lock config:@{}", redisProperties);
        Assert.notNull(redisProperties,"require redis properties");
        Assert.hasLength(redisProperties.getHost(),"require redis host");
        RedisURI.create(redisProperties.getHost(),redisProperties.getPort());
        RedisURI.Builder builder = RedisURI.builder()
                .withHost(redisProperties.getHost())
                .withPort(redisProperties.getPort())
                .withDatabase(redisProperties.getDatabase());
        if(StringUtils.hasLength(redisProperties.getPassword())){
            builder.withPassword(redisProperties.getPassword());
        }
        RedisClient redisClient =RedisClient.create(builder.build());
        return new LettuceLock(redisClient);
    }

    public DefaultPointcutAdvisor defaultPointcutAdvisor(RedisLockable redisLockable){
        RedisLockMethodInterceptor interceptor = new RedisLockMethodInterceptor(redisLockable);
        Pointcut pointcut = new AnnotationMatchingPointcut(Service.class, RedisLock.class, true);
        return new DefaultPointcutAdvisor(pointcut, interceptor);
    }
}
